#include "base/logfile.h"
#include "base/logstream.h"
#include "base/thread.h"
#include "base/config.h"

#include <unistd.h>
#include <sys/syscall.h>

#include "base/log.h"

namespace net_tools
{

  __thread base::Logstream *Log::logstream_ = nullptr;
  base::Logfile *Log::logfile_ = nullptr;
  base::Logstream::Log_level Log::level_ = static_cast<base::Logstream::Log_level>(_C::SET_LOG_OUTPUT_LEVEL);
  func Log::flush_ = Log::Defaultflush;
  Log::outputfunc Log::output_ = Log::Defaultoutput;

  Log::Log(std::string app_name)
      : app_name_(std::move(app_name))
  {
    Init();
  };
  Log::~Log(){};
  base::Logstream *Log::Init()
  {
    base::Thread::thread_tid_ = syscall(SYS_gettid);
    static base::Logstream logstream(base::Thread::thread_tid_);
    if (!logstream_)
    {
      logstream_ = &logstream;
      return logstream_;
    }
    return nullptr;
  };
  void Log::Init(net_tools::Eventloop *eventloop, FILE *file_stream)
  {
    Log::logfile_ = new base::Logfile(app_name_, eventloop, file_stream);
    flush_ = Flush;
    output_ = Output;
    NT_LOG_TRACE << "LOGSTREAM OK" << NT_LOG_ENDL;
  };
  void Log::Use_file_flush_file()
  {
    Log::logfile_->Use_file_flush_file();
  };
  void Log::Set_level(base::Logstream::Log_level level)
  {
    level_ = level;
  };
  void Log::Setstream(FILE *stream)
  {
    Log::logfile_->Setstream(stream);
  };
  void Log::Flush()
  {
    Log::logfile_->Flush();
  };
  void Log::Output(void *address, short int len)
  {
    Log::logfile_->Output(address, len);
  };
  void Log::Defaultflush()
  {
    fflush(stdout);
  };
  void Log::Defaultoutput(void *address, short int len)
  {
    fwrite_unlocked(address, 1, len, stdout);
  };

} // namespace net_tools